package com.easychat.controller;

import com.easychat.annotation.GlobalInterceptor;
import com.easychat.entity.dto.TokenUserInfoDTO;
import com.easychat.entity.dto.UserContactSearchResultDTO;
import com.easychat.entity.enums.PageSize;
import com.easychat.entity.enums.ResponseCodeEnum;
import com.easychat.entity.enums.UserContactStatusEnum;
import com.easychat.entity.enums.UserTypeEnum;
import com.easychat.entity.po.GroupInfo;
import com.easychat.entity.po.UserContact;
import com.easychat.entity.po.UserContactApply;
import com.easychat.entity.po.UserInfo;
import com.easychat.entity.query.UserContactApplyQuery;
import com.easychat.entity.query.UserContactQuery;
import com.easychat.entity.vo.PaginationResultVO;
import com.easychat.entity.vo.ResponseVO;
import com.easychat.entity.vo.UserInfoVO;
import com.easychat.exception.BusinessException;
import com.easychat.service.GroupInfoService;
import com.easychat.service.UserContactApplyService;
import com.easychat.service.UserContactService;
import com.easychat.service.UserInfoService;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;

@RestController("userContactController")
@RequestMapping("/contact")
public class UserContactController extends ABaseController{
    //TODO DONE
    @Resource
    private UserContactService userContactService;//联系人信息
    @Resource
    private UserInfoService userInfoService;//用户信息
    @Resource
    private UserContactApplyService userContactApplyService;//申请信息
    @Resource
    private GroupInfoService groupInfoService;

    /**
     * 搜索好友或者群聊
     * @param contactId
     * @return
     */
    @RequestMapping("/search")
    @GlobalInterceptor
    public ResponseVO search(HttpServletRequest request, @NotEmpty String contactId) {
        TokenUserInfoDTO tokenUserInfoDTO = getTokenUserInfoDTO(request);
        UserContactSearchResultDTO userContactSearchResultDTO = userContactService.search(tokenUserInfoDTO.getUserId(), contactId);
        return getSuccessResponseVO(userContactSearchResultDTO);
    }

    /**
     * 申请加好友或者入群申请
     * @param contactId 联系人id
     * @param applyInfo 申请信息
     * @return
     */
    @RequestMapping("/applyAdd")
    @GlobalInterceptor
    public ResponseVO applyAdd(
            HttpServletRequest request,
            @NotEmpty
            String contactId,
            String applyInfo
    ) {
        TokenUserInfoDTO tokenUserInfoDTO = getTokenUserInfoDTO(request);
        Integer joinType = userContactService.applyAdd(tokenUserInfoDTO, contactId, applyInfo);
        return getSuccessResponseVO(joinType);
    }

    /**
     * 获取好友申请列表(被申请者获取好友申请列表)
     * @param request
     * @param pageNo 页码
     * @return
     */
    @RequestMapping("/loadApply")
    @GlobalInterceptor
    public ResponseVO loadApply(
            HttpServletRequest request,
            Integer pageNo
    ) {
        TokenUserInfoDTO tokenUserInfoDTO = getTokenUserInfoDTO(request);
        UserContactApplyQuery userContactApplyQuery = new UserContactApplyQuery();
        userContactApplyQuery.setReceiveUserId(tokenUserInfoDTO.getUserId());//被申请者获取好友申请列表
        //是否关联查询申请人用户名(apply_user_id)、申请加群的群名(contact_id)
        //详情见NAVICAT的loadApplysql文件
        userContactApplyQuery.setQueryContactInfo(true);
        userContactApplyQuery.setOrderBy("last_apply_time desc");
        userContactApplyQuery.setPageNo(pageNo);
        userContactApplyQuery.setPageSize(PageSize.SIZE15.getSize());
        PaginationResultVO<UserContactApply> pageResult = userContactApplyService.findListByPage(userContactApplyQuery);
        return getSuccessResponseVO(pageResult);
    }

    /**
     * 处理联系人申请
     * @param request
     * @param applyId 申请的id(对应自增id)
     * @param status 申请状态 已同意、已拒绝、拉黑
     * @return
     */
    @RequestMapping("/dealWithApply")
    @GlobalInterceptor
    public ResponseVO dealWithApply(
            HttpServletRequest request,
            @NotNull
            Integer applyId,
            @NotNull
            Integer status
    ) {
        TokenUserInfoDTO tokenUserInfoDTO = getTokenUserInfoDTO(request);
        String receiveUserId = tokenUserInfoDTO.getUserId();
        userContactApplyService.dealWithApply(receiveUserId, applyId, status);
        return getSuccessResponseVO(null);
    }

    /**
     * 获取联系人列表
     * @param request
     * @param contactType 联系人类型
     * @return
     */
    @RequestMapping("/loadContact")
    @GlobalInterceptor
    public ResponseVO loadContact(
            HttpServletRequest request,
            @NotEmpty
            String contactType
    ) {
        TokenUserInfoDTO tokenUserInfoDTO = getTokenUserInfoDTO(request);
        UserTypeEnum contactTypeEnum = UserTypeEnum.getByName(contactType);
        if (contactTypeEnum == null) {
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        UserContactQuery userContactQuery = new UserContactQuery();
        userContactQuery.setUserId(tokenUserInfoDTO.getUserId());//用户id
        userContactQuery.setContactType(contactTypeEnum.getType());//联系人类型
        if (contactTypeEnum == UserTypeEnum.USER) {
            //需要关联查询联系人昵称等
            userContactQuery.setQueryContactUserInfo(true);
        } else if (contactTypeEnum == UserTypeEnum.GROUP) {
            //需要关联群组信息
            userContactQuery.setQueryGroupInfo(true);
            //显示我加入的群时，排除我创建的群组
            userContactQuery.setExcludeMyGroup(true);
        }
        userContactQuery.setOrderBy("last_update_time desc");
        //设置能看到哪些状态的联系人
        userContactQuery.setContactStatusArray(new Integer[]{
                UserContactStatusEnum.FRIEND.getStatus(),
                UserContactStatusEnum.DELETE_BY.getStatus(),
                UserContactStatusEnum.BLACKLIST_BY.getStatus()
        });
        List<UserContact> userContactList = userContactService.findListByParam(userContactQuery);
        return getSuccessResponseVO(userContactList);
    }

    /**
     * 获取联系人详情 不仅限于联系人列表里的
     * @param request
     * @param contactId 联系人ID
     * @return
     */
    @RequestMapping("/getContactInfo")
    @GlobalInterceptor
    public ResponseVO getContactInfo(
            HttpServletRequest request,
            @NotEmpty
            String contactId
    ) {
        //TODO 这里有问题，在我的群组列表，点群头像也掉这个接口
        //TODO 如果传过来的contactId是群id，会报服务器错误 因为userInfo为null
        TokenUserInfoDTO tokenUserInfoDTO = getTokenUserInfoDTO(request);
        UserTypeEnum userTypeEnum = UserTypeEnum.getByPrefix(contactId);
        if (userTypeEnum == null) {
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        //返回值
        UserInfoVO userInfoVO = new UserInfoVO();
        if (userTypeEnum == UserTypeEnum.GROUP) {
            //contactId为群id的情况
            GroupInfo groupInfo = groupInfoService.getGroupInfoByGroupId(contactId);
            userInfoVO.setNickName(groupInfo.getGroupName());//群名称
            userInfoVO.setUserId(groupInfo.getGroupId());//群id
        } else {
            //contactId为好友id的情况
            UserInfo userInfo = userInfoService.getUserInfoByUserId(contactId);
            BeanUtils.copyProperties(userInfo, userInfoVO);
        }
        //默认状态：非好友
        userInfoVO.setContactStatus(UserContactStatusEnum.FRIEND_NO.getStatus());
        //在联系人表中查：是否有此好友的信息
        UserContact userContact = userContactService.getUserContactByUserIdAndContactId(tokenUserInfoDTO.getUserId(), contactId);
        if (userContact != null && userContact.getStatus().equals(UserContactStatusEnum.FRIEND.getStatus())) {
            userInfoVO.setContactStatus(UserContactStatusEnum.FRIEND.getStatus());
        }
        return getSuccessResponseVO(userInfoVO);
    }

    /**
     * 获取联系人详情 判断对应的联系人是否是前端联系人列表里正常展示的
     * @param request
     * @param contactId 联系人ID
     * @return
     */
    @RequestMapping("/getContactUserInfo")
    @GlobalInterceptor
    public ResponseVO getContactUserInfo(
            HttpServletRequest request,
            @NotEmpty
            String contactId
    ) {
        TokenUserInfoDTO tokenUserInfoDTO = getTokenUserInfoDTO(request);
        //在联系人表中查，判断对应的联系人是否是前端联系人列表里正常展示的
        UserContact userContact = userContactService.getUserContactByUserIdAndContactId(tokenUserInfoDTO.getUserId(), contactId);
        if (userContact == null ||
                   !(   userContact.getStatus().equals(UserContactStatusEnum.FRIEND.getStatus()) ||
                        userContact.getStatus().equals(UserContactStatusEnum.DELETE_BY.getStatus()) ||
                        userContact.getStatus().equals(UserContactStatusEnum.BLACKLIST_BY.getStatus()) )
        ) {
            throw new BusinessException(ResponseCodeEnum.CODE_600);
        }
        UserInfo userInfo = userInfoService.getUserInfoByUserId(contactId);
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtils.copyProperties(userInfo, userInfoVO);
        return getSuccessResponseVO(userInfoVO);
    }

    /**
     * 删除联系人
     * @param request
     * @param contactId 联系人ID
     * @return
     */
    @RequestMapping("/delContact")
    @GlobalInterceptor
    public ResponseVO delContact(
            HttpServletRequest request,
            @NotEmpty
            String contactId
    ) {
        TokenUserInfoDTO tokenUserInfoDTO = getTokenUserInfoDTO(request);
        userContactService.removeUserContact(tokenUserInfoDTO.getUserId(), contactId, UserContactStatusEnum.DELETE);
        return getSuccessResponseVO(null);
    }

    /**
     * 拉黑联系人
     * @param request
     * @param contactId 联系人ID
     * @return
     */
    @RequestMapping("/addContact2BlackList")
    @GlobalInterceptor
    public ResponseVO addContact2BlackList(
            HttpServletRequest request,
            @NotEmpty
            String contactId
    ) {
        TokenUserInfoDTO tokenUserInfoDTO = getTokenUserInfoDTO(request);
        userContactService.removeUserContact(tokenUserInfoDTO.getUserId(), contactId, UserContactStatusEnum.BLACKLIST);
        return getSuccessResponseVO(null);
    }
}


